package org.sk.gsync.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;

import org.sk.gsync.ui.context.AbstractContext;
import org.sk.gsync.ui.context.LoginDialogContext;
import org.sk.gsync.ui.context.LoginFields;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import com.google.gdata.client.GoogleService.CaptchaRequiredException;
import com.google.gdata.util.AuthenticationException;

public class LoginDialog extends DefaultFrame {

    private static final long serialVersionUID = 6431644526053023748L;

    private final JPanel contentPanel = new JPanel();

    private JTextField _gmailEmailText;

    private JPasswordField _passwordText;

    public static final int OK = 0;

    public static final int CANCEL = 1;

    private JTextField _captchaText;

    private JPanel captchaPanel;

    private JLabel _gmailEmailLabel;

    private JLabel _passwordLabel;

    private JLabel _capchaImageLabel;

    /**
     * Create the dialog.
     */
    public LoginDialog() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
    }

    @Override
    public void configure() {
        setBounds(100, 100, 368, 252);
        getContentPane().setLayout(new BorderLayout());
        contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        getContentPane().add(contentPanel, BorderLayout.CENTER);
        contentPanel.setLayout(new BorderLayout(0, 0));
        {
            JPanel fieldsPanel = new JPanel();
            contentPanel.add(fieldsPanel, BorderLayout.WEST);
            {
                _gmailEmailLabel = new JLabel("Gmail Email");
            }
            {
                _gmailEmailText = new JTextField();
                _gmailEmailText.setColumns(10);
            }
            {
                _passwordLabel = new JLabel("Password");
            }
            {
                _passwordText = new JPasswordField();
                _passwordText.setColumns(10);
            }
            GroupLayout gl_fieldsPanel = new GroupLayout(fieldsPanel);
            gl_fieldsPanel.setHorizontalGroup(gl_fieldsPanel
                .createParallelGroup(Alignment.LEADING).addGroup(
                    gl_fieldsPanel
                        .createSequentialGroup()
                        .addGap(28)
                        .addGroup(
                            gl_fieldsPanel
                                .createParallelGroup(Alignment.TRAILING)
                                .addGroup(
                                    gl_fieldsPanel.createSequentialGroup()
                                        .addComponent(_passwordLabel)
                                        .addGap(24))
                                .addGroup(
                                    gl_fieldsPanel.createSequentialGroup()
                                        .addComponent(_gmailEmailLabel)
                                        .addGap(18)))
                        .addGroup(
                            gl_fieldsPanel
                                .createParallelGroup(Alignment.LEADING)
                                .addComponent(_gmailEmailText,
                                    GroupLayout.DEFAULT_SIZE, 220,
                                    Short.MAX_VALUE)
                                .addComponent(_passwordText,
                                    GroupLayout.DEFAULT_SIZE, 221,
                                    Short.MAX_VALUE)).addGap(23)));
            gl_fieldsPanel
                .setVerticalGroup(gl_fieldsPanel.createParallelGroup(
                    Alignment.LEADING).addGroup(
                    gl_fieldsPanel
                        .createSequentialGroup()
                        .addContainerGap(GroupLayout.DEFAULT_SIZE,
                            Short.MAX_VALUE)
                        .addGroup(
                            gl_fieldsPanel
                                .createParallelGroup(Alignment.BASELINE)
                                .addComponent(_gmailEmailText,
                                    GroupLayout.PREFERRED_SIZE,
                                    GroupLayout.DEFAULT_SIZE,
                                    GroupLayout.PREFERRED_SIZE)
                                .addComponent(_gmailEmailLabel))
                        .addGap(16)
                        .addGroup(
                            gl_fieldsPanel
                                .createParallelGroup(Alignment.BASELINE)
                                .addComponent(_passwordText,
                                    GroupLayout.PREFERRED_SIZE,
                                    GroupLayout.DEFAULT_SIZE,
                                    GroupLayout.PREFERRED_SIZE)
                                .addComponent(_passwordLabel)).addGap(75)));
            fieldsPanel.setLayout(gl_fieldsPanel);
        }
        {
            captchaPanel = new JPanel();
            contentPanel.add(captchaPanel, BorderLayout.SOUTH);
            {
                _capchaImageLabel = new JLabel();
                _capchaImageLabel.setBorder(BorderFactory
                    .createLineBorder(Color.RED));
            }

            captchaPanel.setVisible(false);

            JLabel lblVerifyCaptcha = new JLabel("Verify Captcha");
            lblVerifyCaptcha.setHorizontalAlignment(SwingConstants.CENTER);
            {
                _captchaText = new JTextField();
                lblVerifyCaptcha.setLabelFor(_captchaText);
                _captchaText.setColumns(10);
            }
            GroupLayout gl_captchaPanel = new GroupLayout(captchaPanel);
            gl_captchaPanel.setHorizontalGroup(gl_captchaPanel
                .createParallelGroup(Alignment.TRAILING).addGroup(
                    gl_captchaPanel
                        .createSequentialGroup()
                        .addGap(19)
                        .addComponent(_capchaImageLabel,
                            GroupLayout.PREFERRED_SIZE, 149,
                            GroupLayout.PREFERRED_SIZE)
                        .addGap(47)
                        .addGroup(
                            gl_captchaPanel
                                .createParallelGroup(Alignment.TRAILING)
                                .addComponent(lblVerifyCaptcha,
                                    GroupLayout.DEFAULT_SIZE, 86,
                                    Short.MAX_VALUE)
                                .addComponent(_captchaText)).addGap(41)));
            gl_captchaPanel.setVerticalGroup(gl_captchaPanel
                .createParallelGroup(Alignment.LEADING)
                .addGroup(
                    gl_captchaPanel
                        .createSequentialGroup()
                        .addContainerGap()
                        .addComponent(lblVerifyCaptcha,
                            GroupLayout.DEFAULT_SIZE, 14, Short.MAX_VALUE)
                        .addPreferredGap(ComponentPlacement.UNRELATED)
                        .addComponent(_captchaText,
                            GroupLayout.PREFERRED_SIZE,
                            GroupLayout.DEFAULT_SIZE,
                            GroupLayout.PREFERRED_SIZE).addContainerGap())
                .addComponent(_capchaImageLabel, GroupLayout.DEFAULT_SIZE,
                    67, Short.MAX_VALUE));
            captchaPanel.setLayout(gl_captchaPanel);
        }
        {
            JPanel buttonPane = new JPanel();
            buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
            getContentPane().add(buttonPane, BorderLayout.SOUTH);
            {
                JButton okButton = new JButton("OK");
                okButton.addActionListener(new ActionListener() {
                    public void actionPerformed(final ActionEvent e) {
                        selectedOption = OK;
                        updateContext();
                        dispose();
                    }
                });
                okButton.setActionCommand("OK");
                buttonPane.add(okButton);
                getRootPane().setDefaultButton(okButton);
            }
            {
                JButton cancelButton = new JButton("Cancel");
                cancelButton.addActionListener(new ActionListener() {
                    public void actionPerformed(final ActionEvent e) {
                        selectedOption = CANCEL;
                    }
                });
                cancelButton.setActionCommand("Cancel");
                buttonPane.add(cancelButton);
            }
        }
    }

    /**
     * @see org.sk.gsync.ui.DefaultFrame#updateContext()
     */
    @Override
    public void updateContext() {
        getContext().setValue(LoginFields.GMAIL_EMAIL,
            _gmailEmailText.getText());
        getContext().setValue(LoginFields.PASSWORD,
            String.copyValueOf(_passwordText.getPassword()));
        if (_captchaText != null) {
            getContext().setValue(LoginFields.TOKEN,
                _captchaText.getText());
            captchaPanel.setVisible(false);
            _capchaImageLabel.setIcon(null);
        }
    }

    public void login() {
        LoginDialogContext context = ((LoginDialogContext) getContext());
        while (!context.isAuth() || context.isTriesExausted()) {
            try {
                if (open() == LoginDialog.OK) {
                    ((LoginDialogContext) getContext()).login();
                }
            } catch (AuthenticationException e) {
                if (e instanceof CaptchaRequiredException) {
                    CaptchaRequiredException ex =
                        (CaptchaRequiredException) e;
                    try {
                        ImageIcon captcha =
                            new ImageIcon(Toolkit.getDefaultToolkit()
                                .createImage(new URL(ex.getCaptchaUrl())));
                        _capchaImageLabel.setIcon(captcha);
                        captchaPanel.setVisible(true);
                    } catch (MalformedURLException e1) {
                        JOptionPane.showMessageDialog(this,
                            e1.getMessage());
                    }
                } else {
                    JOptionPane.showMessageDialog(this, e.getMessage());
                }
            }
        }
    }

    /**
     * @see org.sk.gsync.ui.DefaultFrame#setContext(org.sk.gsync.ui.context.AbstractContext)
     */
    @Override
    @Autowired
    @Qualifier("loginDialogContext")
    protected void setContext(final AbstractContext context) {
        super.setContext(context);
    }
}
